#import <CoreFoundation/CoreFoundation.h>
#include <sys/socket.h>
#include <netinet/in.h>
#if TARGET_OS_IPHONE
#import <CFNetwork/CFNetwork.h>
#endif

#define PORT 12345
#define ERR -1

void Listen(CFSocketRef, CFSocketCallBackType, CFDataRef, const void *, void *);

int main(int argc, char **argv) 
{
  /* Client Socket */
  CFSocketRef client;

  /* Function name that will be sent to Server*/
  char command[] = "";

  /* Used by setsockopt */
  int yes = 1;

  /* Ties command to socket*/
  CFSocketContext context = { 0, command, NULL, NULL, NULL };

  /* Create Socket */
  client = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketConnectCallBack, (CFSocketCallBack)Listen, &context);
  if (client == NULL)
    return ERR;

  /* Set listening port/address */
  struct sockaddr_in addr;
  memset(&addr, 0, sizeof(addr));
  addr.sin_len = sizeof(addr);
  addr.sin_family = AF_INET;
  addr.sin_port = htons(PORT);
  addr.sin_addr.s_addr = INADDR_ANY;
  CFDataRef connectAddr = CFDataCreate(NULL, (unsigned char *)&addr, sizeof(addr));

  CFSocketConnectToAddress(client, connectAddr, 1);
  CFRunLoopSourceRef sourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault, client, 0);
  CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes);
  CFRelease(sourceRef);
  CFRunLoopRun();

  /* Get on with our life, instead of waiting for a connect. */
  while(1) 
  {
    struct timeval tv;
    tv.tv_usec = 0;
    tv.tv_sec = 1;        
    select(-1, NULL, NULL, NULL, &tv);
  } 

}


void Listen(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
  CFReadStreamRef readStream = NULL;
  CFWriteStreamRef writeStream = NULL;
  CFIndex bytes;
  UInt8 buffer[128];
  UInt8 recv_len = 0, send_len = 0;

  /* The native socket, used for various operations */
  CFSocketNativeHandle sock = CFSocketGetNative(socket);

  /* The joke we stored in the socket context */
  char *joke = info;

  printf("OK. %s", joke);

  send(sock, joke, strlen(joke)+1, 0);
  recv(sock, buffer, sizeof(buffer), 0);
  printf("%sHow lame!\n", buffer);

  close(sock);
  exit(EXIT_SUCCESS);
}

